/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-11-27     SummerGift   add spi flash port file
 */

#include <rtthread.h>
#include "spi_flash.h"
#include "spi_flash_sfud.h"
#include "drv_spi.h"
#include <dfs_elm.h>
#include <dfs_fs.h>
#include <dfs_posix.h>
#include <fal.h>
#define DBG_ENABLE
#define DBG_SECTION_NAME  "app.spi_flash"
#define DBG_COLOR

#define DBG_LEVEL DBG_INFO
#include <rtdbg.h>
#if defined(BSP_USING_SPI_FLASH)
static int spi_flash_init(void); 
static int spi_flash_read(long offset, uint8_t *buf, size_t size); 
static int spi_flash_write(long offset, const uint8_t *buf, size_t size); 
static int spi_flash_erase(long offset, size_t size); 
struct fal_flash_dev spi_flash = { "spi_flash", 0, 8*1024*1024, 4096, {spi_flash_init, spi_flash_read, spi_flash_write, spi_flash_erase} };
static sfud_flash_t sfud_dev = NULL;

static int spi_flash_init(void) 
{  
  
   /* RT-Thread RTOS platform */ 
    sfud_dev = rt_sfud_flash_find_by_dev_name("SPI_Flash"); 

 
    if (NULL == sfud_dev) 
    { 
        return -1; 
    } 

 
     /* update the flash chip information */ 
     spi_flash.blk_size = sfud_dev->chip.erase_gran; 
     spi_flash.len = sfud_dev->chip.capacity; 
 
 
     return 0; 
}  
 
static int spi_flash_read(long offset, uint8_t *buf, size_t size) 
{ 
    assert(sfud_dev); 
  	assert(sfud_dev->init_ok); 
    sfud_read(sfud_dev, spi_flash.addr + offset, size, buf);  
 
    return size; 
} 
 
 
static int spi_flash_write(long offset, const uint8_t *buf, size_t size) 
{ 
    assert(sfud_dev); 
    assert(sfud_dev->init_ok); 
    if (sfud_write(sfud_dev, spi_flash.addr + offset, size, buf) != SFUD_SUCCESS) 
    { 
        return -1; 
    } 
 
    return size; 
} 

 
static int spi_flash_erase(long offset, size_t size) 
{
    assert(sfud_dev); 
    assert(sfud_dev->init_ok); 
    if (sfud_erase(sfud_dev, spi_flash.addr + offset, size) != SFUD_SUCCESS) 
    { 
        return -1; 
    }
    return size; 
} 



static int rt_hw_spi_flash_init(void)
{
    __HAL_RCC_GPIOB_CLK_ENABLE();
    rt_hw_spi_device_attach("spi2", "spi20", GPIOB, GPIO_PIN_12);

    if (RT_NULL == rt_sfud_flash_probe("SPI_Flash", "spi20"))
    {
        return -RT_ERROR;
    };
		
    return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_spi_flash_init);

#if defined(RT_USING_DFS)
void spi_flash_mount(void *parameter)
{
	int rec;

        rt_thread_mdelay(1);
        if(rt_device_find("sdb") != RT_NULL)
        {
            if ((rec=dfs_mount("sdb", "/", "elm", 0, 0)) == RT_EOK)
            {
                LOG_I("sdb mount to '/'");
            }
            else if (dfs_mkfs("elm","sdb") != -1)
            {
							if ((rec=dfs_mount("sdb", "/", "elm", 0, 0)) == RT_EOK)
							{
									LOG_I("sdb mount to '/'");
							}
							else
									LOG_W("sdb mount to '/' failed %d!",rec);
            }
						else
						{
							LOG_W("sdb mount to '/' failed %d!",rec);
						}
        }
    
}

int stm32_spi_flash_mount(void)
{
    rt_thread_t tid;
		
		fal_blk_device_create("sdb");
	
    tid = rt_thread_create("spi_flash_mount", spi_flash_mount, RT_NULL,
                           1024, RT_THREAD_PRIORITY_MAX - 2, 20);
    if (tid != RT_NULL)
    {
        rt_thread_startup(tid);
    }
    else
    {
        LOG_E("create spi_flash_mount thread err!");
    }
    return RT_EOK;
}
INIT_ENV_EXPORT(stm32_spi_flash_mount);
#endif
#endif

